package org.gnomus.data;

import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import org.gnomus.server.C;

import java.util.*;

public class access extends object {

    public access(Entity e) {
        super(e);
        setCode((String) e.getProperty("code"));
        setUsed((Boolean) e.getProperty("used"));
        setCompleted((Boolean) e.getProperty("completed"));
        setScore((String) e.getProperty("score"));
        setMemberKey((Key) e.getProperty("member_key"));
        setAssignmentKey((Key) e.getProperty("assignment_key"));
    }

    public access(member mbr, assignment ant) {
        super("access");
        setCode(createCode());
        setUsed(false);
        setCompleted(false);
        setScore("N/A");
        setMemberKey(mbr.key);
        setAssignmentKey(ant.key);
    }

    public static List<access> fetch(Key ak) {
        List<access> acs_list = new ArrayList<access>();
        Map<String, Object> filters = new HashMap<String, Object>();
        filters.put("assignment_key", ak);
        for (Entity e : store.get("access", filters)) {
            acs_list.add(new access(e));
        }
        return acs_list;
    }

    public void setCode(String code) {
        put("code", code);
    }

    public String getCode() {
        return (String) get("code");
    }

    public void setUsed(Boolean used) {
        put("used", used);
    }

    public Boolean getUsed() {
        return (Boolean) get("used");
    }

    public void setCompleted(Boolean completed) {
        put("completed", completed);
    }

    public Boolean getCompleted() {
        return (Boolean) get("completed");
    }

    public void setScore(String score) {
        put("score", score);
    }

    public String getScore() {
        return (String) get("score");
    }

    public void setMemberKey(Key member_key) {
        put("member_key", member_key);
    }

    public Key getMemberKey() {
        return (Key) get("member_key");
    }

    public member getMember() {
        return new member(store.get(getMemberKey()));
    }

    public void setAssignmentKey(Key assignment_key) {
        put("assignment_key", assignment_key);
    }

    public Key getAssignmentKey() {
        return (Key) get("assignment_key");
    }

    public assignment getAssignment() {
        return new assignment(store.get(getAssignmentKey()));
    }

    public void recordScore(String score) {
        put("score", score);
        setCompleted(true);
        save();
    }

    public static access findByCode(String code) {
        Map<String, Object> filters = new HashMap<String, Object>();
        filters.put("code", code);
        Iterator<Entity> ie = store.get("access", filters).iterator();
        if (ie.hasNext()) {
            return new access(ie.next());
        }
        return null;
    }

    private static String createCode() {
        String code = "";
        for (int i = 0; i < 10; i++) {
            String c1 = C.codes[0][(int)Math.floor(Math.random() * C.codes[0].length)];
            String c2 = C.codes[1][(int)Math.floor(Math.random() * C.codes[1].length)];
            String c3 = C.codes[2][(int)Math.floor(Math.random() * C.codes[2].length)];
            String c4 = C.codes[3][(int)Math.floor(Math.random() * C.codes[3].length)];
            code = c1 + " " + c2 + " " + c3 + " " + c4;
            Map<String, Object> filters = new HashMap<String, Object>(2);
            filters.put("code", code);
            if (!store.get("access", filters).iterator().hasNext()) {
                break;
            }
            if (i > 8) {
                throw new Error("Failed to generate unique code after 8 attempts");
            }
        }
        return code;
    }
}
